﻿//Implentation of the $1 algorithm (Wobbrock, et. al) for use with the Kinect

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Forms;
using System.Xml;
using Microsoft.Kinect;
using Microsoft.Samples.Kinect.KinectExplorer;
using Microsoft.Samples.Kinect.WpfViewers;



namespace ZeroTouchUI
{
    public class RecognizedEventArgs : EventArgs
    {
        public Gesture gesture;
    }

    /// <summary>
    /// This class is used to watch for and recognize recorded gestures
    /// </summary>
    public class GestureRecognizer : Window
    {
        private readonly GR1 gr1;
        private KinectSensor kinect;
        public Profile profile;
        private Mutex mutex;
        public List<KinectSkeleton> skeletons;
        public bool tracking;
        public bool triggering = true;
        public MainWindow main;

        public delegate void RecognizedEventHandler(object sender, RecognizedEventArgs e);
        public event RecognizedEventHandler Recognized;
        public virtual void OnRecognized(RecognizedEventArgs e)
        {
            if (Recognized != null)
                Recognized(this, e);
        }

        public GestureRecognizer()
        {
            this.gr1 = new GR1();
            Content = this.gr1;
            Width = 715;
            Height = 600;
            Title = "Gesture Recognizer";
            this.Closed += new EventHandler(GestureRecognizer_Closed);
            mutex = new Mutex();
            tracking = false;
        }
        public KinectSensor Kinect
        {
            get
            {
                return this.kinect;
            }

            set
            {
                this.kinect = value;
                this.gr1.Kinect = this.kinect;

                if (this.kinect != null)
                {
                    skeletons = new List<KinectSkeleton>
                    {
                        this.gr1.KinectSkeletonViewerOnColor.skeletonCanvas1,
                        this.gr1.KinectSkeletonViewerOnColor.skeletonCanvas2,
                        this.gr1.KinectSkeletonViewerOnColor.skeletonCanvas3,
                        this.gr1.KinectSkeletonViewerOnColor.skeletonCanvas4,
                        this.gr1.KinectSkeletonViewerOnColor.skeletonCanvas5,
                        this.gr1.KinectSkeletonViewerOnColor.skeletonCanvas6
                    };
                    foreach (KinectSkeleton skeleton in skeletons)
                    {
                        skeleton.Changed += new KinectSkeleton.SkeletonChangedEventHandler(skeleton_Changed);
                    }

                    this.kinect.AllFramesReady += new EventHandler<AllFramesReadyEventArgs>(kinect_AllFramesReady);
                }
            }
        }

        private void GestureRecognizer_Closed(object sender, EventArgs e)
        {
            this.Kinect = null;
        }

        private void skeleton_Changed(object sender, RecognizerEventArgs e)
        {
            if (!(sender.GetType().ToString().Contains("KinectSkeleton")))
            {
                return;
            }

            KinectSkeleton ks = (KinectSkeleton)sender;

            // Change the icon when tracking starts happening
            if (ks.Tracking && !tracking)
            {
                tracking = true;
                if (main.recognizerIcon == null)
                {
                    main.recognizerIcon = new NotifyIcon();
                }
                main.recognizerIcon.Visible = false;
                main.recognizerIcon.Text = "NSA Recognizer - Tracking";
                main.recognizerIcon.Icon = new Icon("KinectExplorerTracking.ico");
                main.recognizerIcon.Visible = true;

                //main.Tracking = "Tracking";
            }

            if ((e.leftRecog.Count >= 10 && Dollar.GetBoundingBox(e.leftRecog).height > 100) ||
                (e.leftRecog.Count >= 10 && Dollar.GetBoundingBox(e.leftRecog).width > 100) ||
                (e.rightRecog.Count >= 10 && Dollar.GetBoundingBox(e.rightRecog).height > 100) ||
                (e.rightRecog.Count >= 10 && Dollar.GetBoundingBox(e.rightRecog).width > 100))
            {
                Gesture recognized = Dollar.Recognize(e.leftRecog, e.rightRecog, 0.75);
                if (recognized != null)
                {
                    this.OnRecognized(new RecognizedEventArgs { gesture = recognized });
                    Console.WriteLine("Recognized gesture " + recognized.Name);

                    // Perform Action Here
                    if (triggering)
                    {
                        profile.pc.activate_event(profile.getDictionary()[recognized].Name);
                    }
                    //
                    ks.mutex.WaitOne();
                        ks.leftAction.Clear();
                        ks.rightAction.Clear();
                    ks.mutex.ReleaseMutex();
                }
            }
        }

        private void kinect_AllFramesReady(object sender, AllFramesReadyEventArgs e)
        {
            // Check to make sure tracking is still happening and change the icon if not
            if (!skeletons.Any(s => s.Tracking) && tracking)
            {
                tracking = false;
                if (main.recognizerIcon == null)
                {
                    main.recognizerIcon = new NotifyIcon();
                }
                main.recognizerIcon.Visible = false;
                main.recognizerIcon.Text = "NSA Recognizer - Not Tracking";
                main.recognizerIcon.Icon = new Icon("KinectExplorer.ico");
                main.recognizerIcon.Visible = true;

               // main.Tracking = "Not Found";
            }
        }
    }
}
